package com.mall.mymall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mall.mymall.common.Result;
import com.mall.mymall.dao.dto.AdminDto;
import com.mall.mymall.dao.entity.Administrators;
import com.mall.mymall.dao.entity.Users;
import com.mall.mymall.mapper.AdministratorsMapper;
import com.mall.mymall.service.AdministratorsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 十里坡
 * @since 2025-03-06
 */
@Service
public class AdministratorsServiceImpl extends ServiceImpl<AdministratorsMapper, Administrators> implements AdministratorsService {

    /**
     * 根据用户名获取管理员信息
     *
     * @param username 管理员用户名，用于查询特定的管理员信息
     * @return 返回查询到的管理员对象，如果没有找到则返回null
     */
    @Override
    public Administrators getAdminByUsername(String username) {
        // 使用MyBatis-Plus的QueryWrapper构造查询条件
        QueryWrapper<Administrators> queryWrapper = new QueryWrapper<>();
        // 设置查询条件为用户名等于传入的username参数
        queryWrapper.eq("username", username);
        // 调用getOne方法执行查询并返回结果
        return this.getOne(queryWrapper);
    }

    /**
     * 管理员登录方法
     *
     * 该方法用于验证管理员的用户名和密码，成功登录后返回管理员的相关信息
     * 如果用户名或密码不正确，将抛出运行时异常
     *
     * @param adminDto 管理员登录信息封装对象，包含用户名和密码
     * @return 如果登录成功，返回包含管理员详细信息的AdminDto对象
     * @throws RuntimeException 如果用户名或密码错误，抛出运行时异常
     */
    @Override
    public AdminDto adminLogin(AdminDto adminDto) {
        // 根据用户名获取管理员信息
        Administrators administrators = getAdminByUsername(adminDto.getUsername());
        // 验证管理员存在且密码匹配
        if (administrators != null && administrators.getPassword().equals(adminDto.getPassword())) {
            // 创建并返回新的AdminDto对象，包含管理员的详细信息
            return new AdminDto(
                    administrators.getAdminId(),
                    administrators.getUsername(),
                    administrators.getPassword(),
                    administrators.getNickname(),
                    administrators.getAvatarUrl(),
                    administrators.getRoleId());
        }
        // 如果用户名或密码不正确，抛出异常
        throw new RuntimeException("用户名或密码错误");
    }

    /**
     * 更新管理员的昵称
     *
     * @param adminDto 包含管理员信息的数据传输对象，包括新的昵称
     * @return 更新后的管理员信息DTO，如果昵称未改变则返回当前信息
     * @throws RuntimeException 如果提供的管理员ID无效，抛出运行时异常
     */
    @Override
    public AdminDto updateNickName(AdminDto adminDto) {
        // 根据管理员ID查询数据库中的管理员信息
        Administrators administrators = this.baseMapper.selectById(adminDto.getAdminId());
        if (administrators != null) {
            // 检查数据库中的昵称是否与要更新的昵称相同
            if (administrators.getNickname().equals(adminDto.getNickname())) {
                // 如果昵称未改变，直接返回当前的管理员信息DTO
                return new AdminDto(
                        administrators.getAdminId(),
                        administrators.getUsername(),
                        administrators.getPassword(),
                        administrators.getNickname(),
                        administrators.getAvatarUrl(),
                        administrators.getRoleId());
            }
            // 如果昵称不同，更新数据库中的昵称
            administrators.setNickname(adminDto.getNickname());
            this.baseMapper.updateById(administrators);
            // 返回更新后的管理员信息DTO
            return adminDto;
        }
        // 如果未找到对应的管理员信息，抛出异常
        throw new RuntimeException("无效的userId{}" + adminDto.getAdminId());
    }

    /**
     * 更新管理员密码
     *
     * 此方法首先根据提供的管理员ID查询数据库中的管理员信息如果管理员存在，
     * 它会检查当前密码是否与数据库中的密码匹配如果密码匹配，则返回传入的AdminDto对象
     * 否则，它将更新管理员的密码，并返回更新后的管理员信息如果管理员不存在，
     * 它将抛出一个运行时异常，指示用户ID无效
     *
     * @param adminDto 包含管理员信息和新密码的AdminDto对象
     * @return 更新后的AdminDto对象
     * @throws RuntimeException 如果提供的用户ID无效
     */
    @Override
    public AdminDto updatePassword(AdminDto adminDto) {
        // 根据管理员ID查询数据库中的管理员信息
        Administrators administrators = this.baseMapper.selectById(adminDto.getAdminId());

        // 检查管理员是否存在
        if (administrators != null) {
            // 检查当前密码是否与数据库中的密码匹配
            if (administrators.getPassword().equals(adminDto.getPassword())) {
                // 密码未更改，直接返回传入的AdminDto对象
                return adminDto;
            }
            // 更新管理员的密码
            administrators.setPassword(adminDto.getPassword());
            this.baseMapper.updateById(administrators);

            // 返回更新后的管理员信息
            return new AdminDto(
                    administrators.getAdminId(),
                    administrators.getUsername(),
                    administrators.getPassword(),
                    administrators.getNickname(),
                    administrators.getAvatarUrl(),
                    administrators.getRoleId());
        }
        // 如果管理员不存在，抛出异常
        throw new RuntimeException("无效的userId{}" + adminDto.getAdminId());
    }

    /**
     * 根据管理员DTO查询管理员列表
     * 此方法首先根据AdminDto中的adminId查询对应的管理员信息，
     * 如果该管理员存在且其角色ID为5，则返回所有管理员列表；
     * 否则，抛出“权限不足”的运行时异常
     *
     * @param adminDto 包含管理员查询条件的DTO对象
     * @return 管理员列表如果查询条件不满足，则可能为空
     * @throws RuntimeException 如果管理员的角色ID不是5，抛出“权限不足”的异常
     */
    @Override
    public List<Administrators> queryList(AdminDto adminDto) {
        // 根据管理员ID查询管理员信息
        Administrators administrators = this.baseMapper.selectById(adminDto.getAdminId());
        // 检查查询到的管理员是否非空，且角色ID为5
        if (administrators != null && administrators.getRoleId() != null && administrators.getRoleId() == 5) {
            // 如果条件满足，返回所有管理员列表
            return this.baseMapper.queryAll();
        }
        // 如果条件不满足，抛出权限不足的异常
        throw new RuntimeException("权限不足");
    }

    /**
     * 更新管理员信息的方法
     * 该方法首先检查传入的AdminDto对象是否为空，如果为空则抛出异常
     * 然后，它根据AdminDto中的manageId和adminId分别查询出两个管理员对象
     * 接着，它检查manageAdmin是否具有二级权限，如果是，则进一步检查是否可以修改editAdmin的信息
     * 如果manageAdmin的权限足够且editAdmin存在，则更新editAdmin的信息并返回所有管理员列表
     * 如果权限不足或查询不到管理员，则抛出相应的异常
     *
     * @param adminDto 包含管理员信息的DTO对象，用于传递管理员的更新信息
     * @return 更新后的管理员列表
     * @throws RuntimeException 如果adminDto为空、操作权限不足或进行非法操作，将抛出此异常
     */
    @Override
    public List<Administrators> updateInfo(AdminDto adminDto) {
        // 检查传入参数是否为空，如果为空则抛出异常
        if (adminDto == null) {
            throw new RuntimeException("非法操作");
        }
        // 根据manageId查询管理员信息
        Administrators manageAdmin = this.baseMapper.selectById(adminDto.getManageId());
        // 根据adminId查询需要编辑的管理员信息
        Administrators editAdmin = this.baseMapper.selectById(adminDto.getAdminId());
        // 检查manageAdmin是否具有二级权限
        if (manageAdmin != null && manageAdmin.getRoleId() != null && manageAdmin.getRoleId() == 5) {
            // 这里是二级权限检查
            // 检查editAdmin是否存在且manageAdmin的权限是否大于editAdmin的权限
            if (editAdmin != null && manageAdmin.getRoleId() > editAdmin.getRoleId()) {
                // 修改数据
                editAdmin.setUsername(adminDto.getUsername());
                editAdmin.setNickname(editAdmin.getNickname());
                editAdmin.setPassword(editAdmin.getPassword());
                editAdmin.setRoleId(editAdmin.getRoleId());
                // 更新数据库中的管理员信息
                this.baseMapper.updateById(editAdmin);
                // 返回更新后的所有管理员列表
                return this.baseMapper.queryAll();
            }
            // 如果权限检查失败，抛出异常
            throw new RuntimeException("操作权限不足");
        }
        // 如果manageAdmin没有二级权限，抛出异常
        throw new RuntimeException("非法操作");
    }

    /**
     * 更新管理员的头像链接
     *
     * @param adminDto 管理员数据传输对象，包含要更新的头像链接
     * @return 更新后的管理员数据传输对象
     * @throws RuntimeException 如果找不到指定的管理员，则抛出运行时异常
     */
    @Override
    public AdminDto updateAvatarUrl(AdminDto adminDto) {
        // 根据管理员ID查询数据库中的管理员信息
        Administrators administrators = this.baseMapper.selectById(adminDto.getAdminId());

        // 检查是否找到了对应的管理员
        if (administrators != null) {
            // 更新找到的管理员的头像链接
            administrators.setAvatarUrl(adminDto.getAvatarUrl());

            // 将更新后的管理员信息保存到数据库
            this.baseMapper.updateById(administrators);

            // 创建并返回一个新的管理员数据传输对象，包含更新后的信息
            return new AdminDto(
                    administrators.getAdminId(),
                    administrators.getUsername(),
                    administrators.getPassword(),
                    administrators.getNickname(),
                    administrators.getAvatarUrl(),
                    administrators.getRoleId()
            );
        }

        // 如果没有找到对应的管理员，抛出异常
        throw new RuntimeException("操作非法");
    }
}
